package org.qrd.openmayyam;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.net.MalformedURLException;


/**
 * Parses the web.xml configuration file to invoke the corresponding servlet, else report an error
 *
 * @author Adarsh
 * @author Sivaraman
 * @version $Revision: 1.0.0 $ $Date: 16/10/2008 $
 */


public class ParseXML {

    /**
     * The main method may be used to Test the working of the parser without passing any arguements.
     * By default it would parse the /home/adarsh/sample/WEB-INF/web.xml" file
     */

    public static void main(String args[]) throws MalformedURLException {
        //File webxml=new File(args[0]);
        //String url=args[1];

//	System.out.println("Enter a web.xml file and the URL separated by a space : ");
//	//String url=("http://localhost/c/hello");
//	int subpos=url.toString().indexOf("/");
//	String subcontext=url.toString().substring(subpos+2,url.toString().length());
//	int pos=subcontext.toString().indexOf("/");
//	String context=subcontext.substring(pos,subcontext.length());
//	System.out.println((context));
//	System.out.println(parseXML(context,webxml));
        //new ParseXML().parseXML(new File("D:\\QRD\\deployer\\/WEB-INF/web.xml"));

    }


    /**
     * Returns the servlet class name corresponding to the context name else return an not found error
     *
     * @param contextname The URL pattern whose servlet class is to be searched
     * @param webxml      The complete file name of the web.xml along with the path
     */

    public static String parseXML(String contextname, File webxml) throws MalformedURLException {

        String servletname = "", urlpattern = "", servletclass = "";
        try {
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(webxml);

            // normalize text representation

            doc.getDocumentElement().normalize();

            // The number of servlet tags present in the web.xml file

            NodeList listOfServlets = doc.getElementsByTagName("servlet");

            int totalServlets = listOfServlets.getLength();
            
            System.out.println("total servlet "+totalServlets);

            // The number of servlet mapping  tags present in the web.xml file

            NodeList listOfServletsmapping = doc.getElementsByTagName("servlet-mapping");

            // Parse all the servlet tags

            for (int s = 0; s < listOfServletsmapping.getLength(); s++) {


                Node firstServletNode = listOfServletsmapping.item(s);
                if (firstServletNode.getNodeType() == Node.ELEMENT_NODE) {


                    Element firstServletElement = (Element) firstServletNode;

                    NodeList servletClassList = firstServletElement.getElementsByTagName("url-pattern");
                    Element urlPatternElement = (Element) servletClassList.item(0);

                    NodeList classList = urlPatternElement.getChildNodes();
                    urlpattern = classList.item(0).getNodeValue().trim().toString();
//             
                    if (contextname.equals(urlpattern)) {

                        NodeList servletNameList = firstServletElement.getElementsByTagName("servlet-name");
                        Element servletNameElement = (Element) servletNameList.item(0);

                        NodeList servletList = servletNameElement.getChildNodes();
                        servletname = (servletList.item(0)).getNodeValue().trim();

                        break;
                    }
                }//end of if clause


            }//end of for loop with s var

            //------------------------------------

            // Parse all the servlet mapping tags

            for (int s = 0; s < listOfServlets.getLength(); s++) {


                Node firstServletNode = listOfServlets.item(s);
                if (firstServletNode.getNodeType() == Node.ELEMENT_NODE) {


                    Element firstServletElement = (Element) firstServletNode;

                    //-------
                    NodeList servletNameList = firstServletElement.getElementsByTagName("servlet-name");
                    Element servletNameElement = (Element) servletNameList.item(0);

                    NodeList servletList = servletNameElement.getChildNodes();
                    String thisservletname = servletList.item(0).getNodeValue().trim();

                    //-------
                    NodeList servletClassList = firstServletElement.getElementsByTagName("servlet-class");
                    Element servletClassElement = (Element) servletClassList.item(0);

                    NodeList classList = servletClassElement.getChildNodes();
                    servletclass = classList.item(0).getNodeValue().trim();
//                
                    if (servletname.equals(thisservletname)) {
//                	  
                        return servletclass;
                        //	httpService.registerServlet("/abc", servlet, new Hashtable(), httpContext);


                    }

                }//end of if clause


            }//end of for loop with s var

            //------------------------------------------------------------------


        } catch (SAXParseException err) {
            System.out.println("** Parsing error" + ", line "
                    + err.getLineNumber() + ", uri " + err.getSystemId());
            System.out.println(" " + err.getMessage());

        } catch (SAXException e) {
            Exception x = e.getException();
            ((x == null) ? e : x).printStackTrace();

        } catch (Throwable t) {
            t.printStackTrace();
        }

        return "405 error";
    }

    /**
     * Returns a string array that contains the URL Pattern, Servlet name and Servlet class of each servlet in the web.xml tag
     * If nothing is present, then a null value is returned.
     *
     * @param webxml  The web.xml file (the complete path) that is to be parsed
     * @param warfile The WAR file name whose web.xml is being parsed
     */

    public String[][] parseXML(File webxml, String warfile) throws MalformedURLException {

        String servletname = "", urlpattern = "", servletclass = "";
        String contexts[][] = new String[10][10];
        int i = 0;//, j = 0;
        try {
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(webxml);
            System.out.println("inside parseXML : " + webxml.getAbsolutePath());

            // normalize text representation
            doc.getDocumentElement().normalize();

            NodeList listOfServlets = doc.getElementsByTagName("servlet");

            int totalServlets = listOfServlets.getLength();

            System.out.println("total servlets"+totalServlets);
            NodeList listOfServletsmapping = doc.getElementsByTagName("servlet-mapping");
            // System.out.println("servlet mapping : " +listOfServletsmapping.getLength() );


            for (int s = 0; s < listOfServletsmapping.getLength(); s++) {


                Node firstServletNode = listOfServletsmapping.item(s);
                if (firstServletNode.getNodeType() == Node.ELEMENT_NODE) {


                    Element firstServletElement = (Element) firstServletNode;

                    NodeList servletClassList = firstServletElement.getElementsByTagName("url-pattern");
                    Element urlPatternElement = (Element) servletClassList.item(0);

                    NodeList classList = urlPatternElement.getChildNodes();
                    urlpattern = classList.item(0).getNodeValue().trim().toString();

                    NodeList servletNameList = firstServletElement.getElementsByTagName("servlet-name");
                    Element servletNameElement = (Element) servletNameList.item(0);

                    NodeList servletList = servletNameElement.getChildNodes();
                    servletname = (servletList.item(0)).getNodeValue().trim();


                }//end of if clause
//          System.out.println("url pattern : " + urlpattern);
//          System.out.println("servlet name : " + servletname);

//      }//end of for loop with s var

                //------------------------------------

                for (int s1 = 0; s1 < listOfServlets.getLength(); s1++) {


                    Node firstServletNode1 = listOfServlets.item(s1);
                    if (firstServletNode1.getNodeType() == Node.ELEMENT_NODE) {


                        Element firstServletElement1 = (Element) firstServletNode1;

                        //-------
                        NodeList servletNameList1 = firstServletElement1.getElementsByTagName("servlet-name");
                        Element servletNameElement1 = (Element) servletNameList1.item(0);

                        NodeList servletList1 = servletNameElement1.getChildNodes();
                        String thisservletname1 = servletList1.item(0).getNodeValue().trim();

                        //-------
                        NodeList servletClassList1 = firstServletElement1.getElementsByTagName("servlet-class");
                        Element servletClassElement1 = (Element) servletClassList1.item(0);

                        NodeList classList1 = servletClassElement1.getChildNodes();
                        servletclass = classList1.item(0).getNodeValue().trim();
                        if (thisservletname1.equals(servletname)) {
                            //		  System.out.println("hi");
                            String path = servletclass.replace('.', '\\');
                            path="/"+path;
//                		  path="/home/adarsh/sample/WEB-INF/classes/"+path+".class";
                            //path="/home/adarsh/"+warfile+"/WEB-INF/classes/"+path+".class";

                            ServerConfiguration serverConfiguration = ServerConfiguration.getServerConfiguration();
                            String omHome = serverConfiguration.serverProperties.getProperty("OPEN_MAYYAM_HOME");
                            String omDocRoot = serverConfiguration.serverProperties.getProperty("DOC_ROOT");
                            String omClassesPath = serverConfiguration.serverProperties.getProperty("CLASSES_PATH");
                            String omWarPath = omHome + omDocRoot;

                            path = omWarPath + warfile + omClassesPath + path + ".class";
                            contexts[i][0] = urlpattern;
                            contexts[i][1] = path;
                            contexts[i++][2] = servletclass;
                            System.out.println("class name"+contexts[i - 1][0] + "\n" + contexts[i - 1][1] + "\n" + contexts[i - 1][2] + "\n");
System.out.println("path"+path);
                            //httpService.registerServlet(urlpattern, path, new Hashtable(), httpContext);

                        }


                    }//end of if clause
//          System.out.println("Servlet class : " + servletclass);
//          System.out.println("servlet name : " + servletname);


                }//end of for loop with s var*/

            }

            //------------------------------------------------------------------
            return contexts;


        } catch (SAXParseException err) {
            System.out.println("** Parsing error" + ", line "
                    + err.getLineNumber() + ", uri " + err.getSystemId());
            System.out.println(" " + err.getMessage());

        } catch (SAXException e) {
            Exception x = e.getException();
            ((x == null) ? e : x).printStackTrace();

        } catch (Throwable t) {
            t.printStackTrace();
        }
        return null;

        //return "404 error";
    }

}



